/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制
 */
package co.yixiang.controller.manager.shop;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.common.annotation.AnonymousAccess;
import co.yixiang.common.annotation.Log;
import co.yixiang.common.annotation.NoRepeatSubmit;
import co.yixiang.common.enums.OrderLogEnum;
import co.yixiang.common.exception.BadRequestException;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.modules.activity.service.YxStorePinkService;
import co.yixiang.modules.member.entity.domain.YxUser;
import co.yixiang.modules.member.service.YxUserService;
import co.yixiang.modules.mp.service.YxTemplateService;
import co.yixiang.modules.order.order.entity.domain.YxStoreOrder;
import co.yixiang.modules.order.order.entity.domain.YxStoreOrderStatus;
import co.yixiang.modules.order.order.entity.dto.OrderCountDto;
import co.yixiang.modules.order.order.entity.dto.StoreOrderExpress;
import co.yixiang.modules.order.order.entity.dto.YxStoreOrderDto;
import co.yixiang.modules.order.order.entity.dto.YxStoreOrderQueryCriteria;
import co.yixiang.modules.order.order.entity.enums.OrderStatusEnum;
import co.yixiang.modules.order.order.service.YxStoreOrderService;
import co.yixiang.modules.order.order.service.YxStoreOrderStatusService;
import co.yixiang.modules.shop.entity.dto.ExpressInfo;
import co.yixiang.modules.shop.entity.dto.WechatUserDto;
import co.yixiang.modules.shop.entity.dto.YxExpressDto;
import co.yixiang.modules.shop.entity.param.ExpressParam;
import co.yixiang.modules.shop.service.ExpressService;
import co.yixiang.modules.shop.service.YxExpressService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author hupeng
 * @date 2019-10-14
 */
@Api(tags = "商城:订单管理")
@RestController
@RequestMapping("api/yxStoreOrder")
@Slf4j
public class StoreOrderController {

    @Value("${yshop.apiUrl}")
    private String apiUrl;
    @Autowired
    private  IGenerator generator;
    @Autowired
    private  YxStoreOrderService yxStoreOrderService;
    @Autowired
    private  YxStoreOrderStatusService yxStoreOrderStatusService;
    @Autowired
    private  YxExpressService yxExpressService;
    @Autowired
    private  YxUserService userService;

    @Autowired
    private  YxTemplateService templateService;
    @Autowired
    private  ExpressService expressService;
    @Autowired
    private YxStorePinkService storePinkService;

    /**@Valid
     * 根据商品分类统计订单占比
     */
    @GetMapping("/orderCount")
    @ApiOperation(value = "根据商品分类统计订单占比", notes = "根据商品分类统计订单占比", response = ExpressParam.class)
    public ResponseEntity orderCount() {
        OrderCountDto orderCountDto = yxStoreOrderService.getOrderCount();
        return new ResponseEntity(orderCountDto, HttpStatus.OK);
    }

    @GetMapping(value = "/data/count")
    @AnonymousAccess
    public ResponseEntity getCount() {
        return new ResponseEntity(yxStoreOrderService.getOrderTimeData(), HttpStatus.OK);
    }

    @GetMapping(value = "/data/chart")
    @AnonymousAccess
    public ResponseEntity getChart() {
        return new ResponseEntity(yxStoreOrderService.chartCount(), HttpStatus.OK);
    }


    @ApiOperation(value = "查询订单")
    @GetMapping
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_SELECT')")
    public ResponseEntity getYxStoreOrders(YxStoreOrderQueryCriteria criteria, Pageable pageable) {

        if (ObjectUtil.isNotEmpty(criteria.getOrderStatus()) && criteria.getOrderStatus().equals("ALL")) {
            criteria.setOrderStatus(null);
        }
        return new ResponseEntity(yxStoreOrderService.queryAll(criteria, pageable), HttpStatus.OK);
    }


    @NoRepeatSubmit
    @ApiOperation(value = "发货")
    @PutMapping(value = "/deliver")
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity deliver(@Validated @RequestBody StoreOrderExpress resources) {
        if (StrUtil.isBlank(resources.getLogisticsName())) {
            throw new BadRequestException("请选择快递公司");
        }
        if (StrUtil.isBlank(resources.getLogisticsNo())) {
            throw new BadRequestException("快递单号不能为空");
        }
        YxExpressDto expressDTO = generator.convert(yxExpressService.getById(Integer.valueOf(resources
                .getLogisticsName())), YxExpressDto.class);
        if (ObjectUtil.isNull(expressDTO)) {
            throw new BadRequestException("请先添加快递公司");
        }
        resources.setLogisticsCode(expressDTO.getCode());
        resources.setLogisticsName(expressDTO.getName());
        yxStoreOrderService.deliverGoods(resources);
        return new ResponseEntity(HttpStatus.OK);
    }

    @NoRepeatSubmit
    @ApiOperation(value = "订单核销")
    @PutMapping(value = "/check")
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity check(@Validated @RequestBody YxStoreOrder resources) {
        if (StrUtil.isBlank(resources.getVerifyCode())) {
            throw new BadRequestException("核销码不能为空");
        }
        final YxStoreOrder storeOrder = yxStoreOrderService.getBySn(resources.getSn());
        if (!resources.getVerifyCode().equals(storeOrder.getVerifyCode())) {
            throw new BadRequestException("核销码不对");
        }
        if (storeOrder.getOrderStatus().equals(OrderStatusEnum.UNPAID.name())) {
            throw new BadRequestException("订单未支付");
        }
        if (storeOrder.getOrderStatus().equals(OrderStatusEnum.COMPLETED.name())) {
            throw new BadRequestException("订单已核销");
        }
//        if(storeOrder.getCombinationId() > 0 && storeOrder.getPinkId() > 0){
//            YxStorePinkDTO storePinkDTO = storePinkService.findById(storeOrder.getPinkId());
//            if(!OrderInfoEnum.PINK_STATUS_2.getValue().equals(storePinkDTO.getStatus())){
//                throw new BadRequestException("拼团订单暂未成功无法核销");
//            }
//        }
        //远程调用API
        RestTemplate rest = new RestTemplate();
        String url = StrUtil.format(apiUrl + "/order/admin/order_verific/{}", resources.getVerifyCode());
        String text = rest.getForObject(url, String.class);

        JSONObject jsonObject = JSON.parseObject(text);

        Integer status = jsonObject.getInteger("status");
        String msg = jsonObject.getString("msg");

        if (status != 200) {
            throw new BadRequestException(msg);
        }


        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }


    @NoRepeatSubmit
    @ApiOperation(value = "退款")
    @PostMapping(value = "/refund")
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity refund(@Validated @RequestBody YxStoreOrder resources) {
        yxStoreOrderService.refund(resources);

        //模板消息通知
        try {
            String openid = this.getUserOpenid(resources.getUid());
            if(StrUtil.isNotBlank(openid)){
                templateService.refundSuccessNotice(resources.getSn(),
                        resources.getPayPrice().toString(), openid, DateUtil.formatTime(new Date()));
            }
        } catch (Exception e) {
            log.info("当前用户不是微信用户不能发送模板消息哦!");
        }
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }


    @Log("删除")
    @ApiOperation(value = "删除")
    @DeleteMapping(value = "/{id}")
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_DELETE')")
    public ResponseEntity delete(@PathVariable Integer id) {

        yxStoreOrderService.removeById(id);
        return new ResponseEntity(HttpStatus.OK);
    }

    @NoRepeatSubmit
    @Log("修改订单")
    @ApiOperation(value = "修改订单")
    @PostMapping(value = "/edit")
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity editOrder(@RequestBody YxStoreOrder resources) {
        if (ObjectUtil.isNull(resources.getPayPrice())) {
            throw new BadRequestException("请输入支付金额");
        }
        if (resources.getPayPrice().doubleValue() < 0) {
            throw new BadRequestException("金额不能低于0");
        }

        YxStoreOrderDto storeOrder = generator.convert(yxStoreOrderService.getById(resources.getId()), YxStoreOrderDto.class);
        //判断金额是否有变动,生成一个额外订单号去支付

        int res = NumberUtil.compare(storeOrder.getPayPrice().doubleValue(), resources.getPayPrice().doubleValue());
        if (res != 0) {
            String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
            resources.setExtendOrderId(orderSn);
        }

        yxStoreOrderService.saveOrUpdate(resources);
        YxStoreOrderStatus storeOrderStatus = new YxStoreOrderStatus();
        storeOrderStatus.setOid(resources.getId());
        storeOrderStatus.setChangeType(OrderLogEnum.ORDER_EDIT.getValue());
        storeOrderStatus.setChangeMessage("修改订单价格为：" + resources.getPayPrice());
        storeOrderStatus.setChangeTime(new Date());

        yxStoreOrderStatusService.save(storeOrderStatus);
        return new ResponseEntity(HttpStatus.OK);
    }

    @NoRepeatSubmit
    @Log("修改订单备注")
    @ApiOperation(value = "修改订单备注")
    @PostMapping(value = "/remark")
    @PreAuthorize("hasAnyRole('admin','common','common','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity editOrderRemark(@RequestBody YxStoreOrder resources) {
        if (StrUtil.isBlank(resources.getRemark())) {
            throw new BadRequestException("请输入备注");
        }
        yxStoreOrderService.saveOrUpdate(resources);
        return new ResponseEntity(HttpStatus.OK);
    }
    /**
     * 获取物流信息, 根据传的订单编号 ShipperCode快递公司编号 和物流单号,
     */
    @PostMapping("/express")
    @ApiOperation(value = "获取物流信息", notes = "获取物流信息", response = ExpressParam.class)
    public ResponseEntity express(@RequestBody ExpressParam expressInfoDo) {
        ExpressInfo expressInfo = expressService.getExpressInfo(expressInfoDo.getOrderCode(),
                expressInfoDo.getShipperCode(), expressInfoDo.getLogisticCode());
        if (!expressInfo.isSuccess()) {
            throw new BadRequestException(expressInfo.getReason());
        }
        return new ResponseEntity(expressInfo, HttpStatus.OK);
    }

    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("hasAnyRole('admin','common','common','cate:list')")
    public void download(HttpServletResponse response,
                         YxStoreOrderQueryCriteria criteria,
                         Pageable pageable,
                         @RequestParam(name = "orderStatus") String orderStatus,
                         @RequestParam(name = "orderType") String orderType,
                         @RequestParam(name = "listContent") String listContent) throws IOException, ParseException {
        List<YxStoreOrderDto> list;
        if (StringUtils.isEmpty(listContent)) {
            list = (List) getYxStoreList(criteria, pageable, orderStatus, orderType).get("content");
        } else {
            List<String> idList = JSONArray.parseArray(listContent).toJavaList(String.class);
            list = (List) yxStoreOrderService.queryAll(idList).get("content");
        }
        yxStoreOrderService.download(list, response);
    }

    public Map<String, Object> getYxStoreList(YxStoreOrderQueryCriteria criteria,
                                              Pageable pageable,
                                              String orderStatus,
                                              String orderType) {
        return yxStoreOrderService.queryAll(criteria, pageable);
    }

    /**
     * 获取openid
     * @param uid uid
     * @return String
     */
    private String getUserOpenid(String uid){
        YxUser yxUser = userService.getById(uid);
        if(yxUser == null) {
            return "";
        }

        WechatUserDto wechatUserDto = yxUser.getWxProfile();
        if(wechatUserDto == null) {
            return "";
        }
        if(StrUtil.isBlank(wechatUserDto.getOpenid())) {
            return "";
        }
        return wechatUserDto.getOpenid();

    }

}
